package calculators;

import algorithm.AlgorithmParameters;
import herd.Food;
import herd.Krill;
import utils.Position;
import utils.PositionMath;


public class BetaCalculator {
    private final PositionMath positionMath = new PositionMath();
    private final TendencyCalculator tendencyCalculator = new TendencyCalculator();

    public Position calculateBeta(Krill krill, Food food, AlgorithmParameters parameters) {
        Position betaFood = calculateBetaFood(parameters,food,krill);
        Position betaBest = calculateBetaBest(krill,parameters);

        return positionMath.addPositions(betaFood,betaBest);
    }

    private Position calculateBetaFood(AlgorithmParameters parameters,Food food, Krill krill ) {
        double foodCoefficient = calculateFoodCoefficient(parameters);
        double relatedFitness = tendencyCalculator.calculateRelatedFitness(food.getFitnessValue(),krill.getFitnessValue(),parameters);
        Position relatedPosition = tendencyCalculator.calculateRelatedPosition(food.getPosition(),krill.getPosition());

        positionMath.multiplyPositionImplicitly(relatedPosition,foodCoefficient);
        positionMath.multiplyPositionImplicitly(relatedPosition,relatedFitness);

        return relatedPosition;
    }
    //TO DO finish this one
    private Position calculateBetaBest(Krill krill, AlgorithmParameters parameters) {
        Position bestRelatedPosition = tendencyCalculator.calculateRelatedPosition(krill.getBestPosition(),krill.getPosition());
        double bestFitness = tendencyCalculator.calculateRelatedFitness(krill.getBestPositionFitness(),krill.getFitnessValue(),parameters);
        positionMath.multiplyPositionImplicitly(bestRelatedPosition,bestFitness);

        return bestRelatedPosition;
    }

    private double calculateFoodCoefficient(AlgorithmParameters parameters) {
        return 2.0 * (1.0 - parameters.getIterationRatio());
    }
}
